import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import threading

# 定义 load_image 函数，用于载入用户选择的图片
def load_image():
    global img, img_original, img_tk, canvas
    filepath = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg *.jpeg *.png")])
    if not filepath:
        return
    img_original = Image.open(filepath)
    max_size = 350
    if img_original.size[0] > max_size or img_original.size[1] > max_size:
        img_original.thumbnail((max_size, max_size))
    img = img_original.copy()
    update_image()

# 定义 update_image 函数，用于更新图片及其直方图
def update_image():
    global img, img_tk, canvas, fig
    if img is None:
        return

    def process_image():
        global img, img_tk, canvas, fig
        # 调整亮度
        img_np = np.array(img_original).astype(float)
        scale = brightness_scale.get()
        img_np = img_np * scale
        img_np = np.clip(img_np, 0, 255)
        img_bright = Image.fromarray(img_np.astype(np.uint8))

        # 调整对比度
        img_bright_np = cv2.cvtColor(np.array(img_bright), cv2.COLOR_RGB2GRAY)
        limit = contrast_scale.get()
        clahe = cv2.createCLAHE(clipLimit=limit)
        img_clahe_np = clahe.apply(img_bright_np)

        # 生成高斯模糊
        blur = blur_scale.get()
        blur = 2 * blur + 1
        img_clahe_np = cv2.GaussianBlur(img_clahe_np, (blur, blur), 0)
        img_clahe_np = np.clip(img_clahe_np, 0, 255)

        # 将numpy数组转换回PIL图像对象
        img_clahe_pil = Image.fromarray(img_clahe_np)

        # 更新图片
        img_tk = ImageTk.PhotoImage(img_clahe_pil)
        image_label.config(image=img_tk)

        # 更新直方图
        fig.clear()
        ax = fig.add_subplot(111)
        ax.hist(img_clahe_np.ravel(), bins=256, histtype='stepfilled', color='b', alpha=0.7)
        ax.set_xlabel('Pixel range: 0~255')
        ax.set_ylabel('Pixel count')
        canvas.draw()

    # 使用线程处理图像更新，避免阻塞主线程
    threading.Thread(target=process_image).start()

# 初始化全局变量
img = None
img_original = None
img_tk = None
canvas = None

# 创建主窗口
root = tk.Tk()

# 创建载入图片按钮
load_button = tk.Button(root, text="Load Image", command=load_image)
load_button.pack()

# 创建图片显示标签
image_label = tk.Label(root)
image_label.pack()

# 创建一个新的框架
frame = tk.Frame(root)
frame.pack(fill='x', expand=True)

# 创建亮度调节滑块
brightness_scale = tk.Scale(frame, from_=0.1, to=3.0, resolution=0.1, label="亮度", orient="horizontal", command=lambda x: update_image())
brightness_scale.set(1.0)
brightness_scale.pack(side='left', fill='none', expand=True, padx=5, pady=5)

# 创建对比度调节滑块
contrast_scale = tk.Scale(frame, from_=1.0, to=10.0, resolution=1.0, label="对比度", orient="horizontal", command=lambda x: update_image())
contrast_scale.set(1.0)
contrast_scale.pack(side='left', fill='none', expand=True, padx=5, pady=5)

# 创建高斯模糊滑块
blur_scale = tk.Scale(frame, from_=0, to=10, resolution=1, label="高斯模糊", orient="horizontal", command=lambda x: update_image())
blur_scale.set(0)
blur_scale.pack(side='left', fill='none', expand=True, padx=5, pady=5)

# 创建直方图绘图区
fig = plt.figure(figsize=(6, 4))
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack()

# 启动主循环
root.mainloop()
